package stone926.mods.more_enchantments.mixins;

import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LightningEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;
import stone926.mods.more_enchantments.enchantments.legendary.PurgeEnchantment;
import stone926.mods.more_enchantments.enchantments.negative.BurningEnchantment;
import stone926.mods.more_enchantments.interfaces.IEntitySpawnedByFlower;
import stone926.mods.more_enchantments.interfaces.ILightningEntity;
import stone926.mods.more_enchantments.interfaces.ILogCooldown;
import stone926.mods.more_enchantments.mixins.accessors.LivingEntityAccessor;
import stone926.mods.more_enchantments.mixins.accessors.WorldAccessor;

import java.util.UUID;

@Mixin(Entity.class)
@SuppressWarnings("all")
public abstract class EntityMixin implements IEntitySpawnedByFlower, ILogCooldown {

  @Shadow
  private int fireTicks;
  private boolean fromBlackManda = false;
  private int cornelLogCooldown = 0;
  private int mandalaLogCooldown = 0;

  @Shadow
  public abstract void setFireTicks(int ticks);

  @Shadow
  protected abstract void fall(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition);

  @Override
  public int getCornelLogCooldown() {
    return cornelLogCooldown;
  }

  @Override
  public void setCornelLogCooldown(int logCooldown) {
    this.cornelLogCooldown = logCooldown;
  }

  @Override
  public int getMandalaLogCooldown() {
    return mandalaLogCooldown;
  }

  @Override
  public void setMandalaLogCooldown(int logCooldown) {
    this.mandalaLogCooldown = logCooldown;
  }

  @Inject(method = "setOnFireFor", at = @At("HEAD"), cancellable = true)
  private void setOnFireFor(int seconds, CallbackInfo ci) {
    if ((Entity) (Object) this instanceof LivingEntity l && PurgeEnchantment.shouldPutOffFire(l)) {
      ci.cancel();
    }
  }

  @Redirect(method = "onStruckByLightning", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setFireTicks(I)V"))
  private void setFireTicks(Entity instance, int ticks) {
    if ((Entity) (Object) this instanceof LivingEntity l && PurgeEnchantment.shouldPutOffFire(l)) {
      return;
    }
    setFireTicks(fireTicks + 1);
  }

  @Inject(method = "onStruckByLightning", at = @At("HEAD"), cancellable = true)
  private void onStruckByLightning(ServerWorld world, LightningEntity lightning, CallbackInfo ci) {
    UUID owner = ((ILightningEntity) lightning).getOwner();
    if (owner != null) {
      Entity entity = ((WorldAccessor) world).invokeGetEntityLookup().get(owner);
      if (entity != null && ((IEntitySpawnedByFlower) entity).isSpawnedByMandala() && ((IEntitySpawnedByFlower) this).isSpawnedByMandala()) {
        ci.cancel();
      }
    }
  }

  @ModifyVariable(method = "setOnFireFor", at = @At("HEAD"), ordinal = 0)
  private int modifySeconds(int seconds) {
    if ((Entity) (Object) this instanceof LivingEntity l) {
      LivingEntityAccessor la = (LivingEntityAccessor) l;
      int burningLvl = 0;
      for (ItemStack stack : la.getSyncedArmorStacks()) {
        burningLvl += EnchantmentHelper.getLevel(MoreEnchantmentsMod.BURNING, stack);
      }
      burningLvl /= 2;
      return seconds + BurningEnchantment.getExtraBurningSeconds(burningLvl);
    }
    return seconds;
  }

  @Inject(method = "tick", at = @At("HEAD"))
  private void tick(CallbackInfo ci) {
    if (cornelLogCooldown > 0) cornelLogCooldown--;
    else cornelLogCooldown = 0;
  }

  @Override
  public boolean isSpawnedByMandala() {
    return fromBlackManda;
  }

  @Override
  public void setSpawnedByMandala(boolean b) {
    fromBlackManda = b;
  }

}
